﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using cocos2d;
using CampaignWP7.Base;
using Microsoft.Xna.Framework;

namespace CampaignWP7
{
    class Wolf : DynamicsObj
    {
        public float WalkSpeed { set; get; }
        public float width { set; get; }
        public float height { set; get; }
        public int MyScore { set; get; }

        public enum WolfState
        {
            WS_ALIVE = 0,
            WS_HIT,
            WS_DYING,
            WS_TO_BUILDING,

            WS_NUM
        }
        public WolfState CurrentState { set; get; }
        //////////////////////////////////////////////////////////////////////////
        public Balloon m_Balloons;
        public Balloon GetBalloon() { return m_Balloons; }
        public virtual Shield GetShield() { return null; }
        //////////////////////////////////////////////////////////////////////////
        protected static Dictionary<string, List<CCSpriteFrame>> m_framesDict;      

        enum AnimationType
        {
            AT_WALK = 0,
            AT_FLOAT,
            //AT_HIT,
            AT_NUM
        }
        private static string[] ActionsName = { "walk","float","hit" };
        private static int[] ActionsFrameCount = { 7, 5, 1 };

        public Wolf(int balloonNum)
        {
            string wolfTextureName = "wolf";
            WalkSpeed = 2;
            MyScore = 10;
            CurrentState = WolfState.WS_ALIVE;
            m_Balloons = new Balloon(Balloon.BalloonType.BT_COLOR_RED, balloonNum);
            m_Balloons.visible = false;
            //
            if (m_framesDict == null || m_framesDict.Count == 0)
            {
                m_framesDict = new Dictionary<string, List<CCSpriteFrame>>();
                for (int i = 0; i < (int)AnimationType.AT_NUM; ++i)
                {
                    List<CCSpriteFrame> temp = new List<CCSpriteFrame>();
                    //---
                    //every animation type shouldn't greater then N!
                    //---
                    for (int k = 0; k < ActionsFrameCount[i]; ++k)
                    {
                        string frameName = ActionsName[i];
                        //the format of name likes  "bullet_normal_1.png"
                        frameName = wolfTextureName + "_" + frameName + "_" + k + ".png";
                        CCSpriteFrame spriteframe = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName(frameName);
                        if (spriteframe != null)
                        {
                            temp.Add(spriteframe);
                        }
                        //
                        if (k == ActionsFrameCount[i] - 1)
                        {
                            if (temp.Count != 0)
                            {
                                m_framesDict.Add(ActionsName[i], temp);
                            }
                            break;
                        }
                    }
                }
            }
            
            //
            string initName = wolfTextureName + "_" + ActionsName[0] + "_0.png";
            initWithSpriteFrameName(initName);
            CCSpriteFrame frame = CCSpriteFrameCache.sharedSpriteFrameCache().spriteFrameByName(initName);
            width = frame.Rect.size.width;
            height = frame.Rect.size.height;

            anchorPoint = new CCPoint(0.5f, 0.5f);
        }
        //
        public override void update(float dt)
        {
            if (m_Balloons.State == Balloon.BalloonState.BalloonState_Normal)
            {
                CCPoint pos = new CCPoint(position.x, position.y + height * 0.5f);
                m_Balloons.MoveTo(pos);
            }
            base.update(dt);
        }
        //
        public virtual void PlayFloatAnimation()
        {
            CurrentState = WolfState.WS_ALIVE;
            m_Balloons.visible = true;
            //
            List<CCSpriteFrame> temp = m_framesDict[ActionsName[(int)AnimationType.AT_FLOAT]];
            CCAnimation ani = CCAnimation.animationWithFrames(temp);
            CCAnimate action = CCAnimate.actionWithDuration(.8f, ani, true);
            this.runAction(CCRepeatForever.actionWithAction(action));
            //

        }
        //
        public virtual void PlayWalkAnimation()
        {
            CurrentState = WolfState.WS_ALIVE;
            //
            List<CCSpriteFrame> temp = m_framesDict[ActionsName[(int)AnimationType.AT_WALK]];
            CCAnimation ani = CCAnimation.animationWithFrames(temp);
            CCAnimate action = CCAnimate.actionWithDuration(1.0f, ani, true);
            this.runAction(CCRepeatForever.actionWithAction(action));
        }
        //
        public virtual void PlayFallAnimation()
        {
            CurrentState = WolfState.WS_DYING;
            //
            m_Balloons.visible = false;
            m_Balloons.State = Balloon.BalloonState.BalloonState_Exploded;
            //-------------
            DynamicMgr.Instance().DelChild(this);
            ResDef.g_BalloonBatchNode.removeChild(m_Balloons,true);
        }
        //
        public void PlayDeadAnimation()
        {
            CurrentState = WolfState.WS_DYING;
        }
        //
        public void PlayMoveToJump(float time,CCPoint pos)
        {
            //
            List<CCFiniteTimeAction> acs = new List<CCFiniteTimeAction>();
            CCFiniteTimeAction moveaction = CCMoveTo.actionWithDuration(time, pos);
            acs.Add(moveaction);
            CCFiniteTimeAction jumpaction = CCCallFuncND.actionWithTarget(this, 
                                                new SEL_CallFuncND(callbackMoveToJump), this);
            acs.Add(jumpaction);
            CCAction move = CCSequence.actions(acs.ToArray());
            this.runAction(move);
        }
        //
        public void callbackMoveToJump(CCNode sender, object data)
        {
            Wolf wolf = (Wolf)data;
            wolf.Velocity = new Vector2(0, -1 * (float)wolf.userData);
            wolf.Acceleration = DynamicsObj.Gravity * (-0.8f);
            wolf.StopAnimation();
            wolf.PlayFloatAnimation();
            //wolf.scheduleUpdateWithPriority(1);
        }
        //
        public void StopAnimation()
        {
            this.stopAllActions();
        }
        //
        public virtual void PlayMoveToBuilding(float time, CCPoint pos)
        {
            CurrentState = WolfState.WS_TO_BUILDING;
            //
            List<CCFiniteTimeAction> acs = new List<CCFiniteTimeAction>();
            CCFiniteTimeAction moveaction = CCMoveTo.actionWithDuration(time, pos);
            acs.Add(moveaction);
            CCFiniteTimeAction jumpaction = CCCallFuncND.actionWithTarget(this, 
                                                new SEL_CallFuncND(callbackMoveToBuilding), this);
            acs.Add(jumpaction);
            CCAction move = CCSequence.actions(acs.ToArray());
            move.tag = (int)CurrentState;
            this.runAction(move);
            //
            m_Balloons.PlayFloatAnimation();
        }
        private void callbackMoveToBuilding(CCNode sender, object data)
        {

        }
    }
}
